package com.glsc.ngateway.platform.service;

import cn.hutool.core.date.DateUtil;
import com.glsc.ngateway.common.base.domain.mysql.gateway.other.EmailClient;
import com.glsc.ngateway.common.base.domain.mysql.gateway.other.SystemConfig;
import com.glsc.ngateway.common.base.repo.mysql.gateway.other.EmailClientRepository;
import com.glsc.ngateway.common.api.common.enums.Constant;
import com.glsc.ngateway.common.api.common.enums.DictConstant;
import com.glsc.ngateway.common.api.common.ex.GatewayException;
import com.glsc.ngateway.platform.utils.SpringUtil;
import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.mail.MailProperties;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.mail.Address;
import javax.mail.MessagingException;
import javax.mail.SendFailedException;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.io.*;
import java.text.MessageFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhouzp
 * @date 2020/6/17
 * 邮件发送服务
 */
@Service
public class MailService {

    private static Logger logger = LoggerFactory.getLogger(MailService.class);

    private static final String SYSTEM_CONFIG_MAIL_SEND_ON = "SYSTEM_CONFIG_MAIL_SEND_ON";

    @Resource(name = "mailSender")
    private JavaMailSender mailSender;

    @Resource(name = "mailSender3")
    private JavaMailSender mailSender3;

    @Resource
    private SystemConfigService systemConfigService;


    @Autowired
    private EmailClientRepository emailClientRepository;
//
//    @Autowired
//    private SystemConfigRepository systemConfigRepository;
//
//    @Resource
//    private SpringTemplateEngine templateEngine;

//    @Resource
//    private MessageSender messageSender;

    public static final String TEST_MAIL_TITLE_PREFIX = "【系统测试邮件】";

//    /**
//     * 渲染模板
//     *
//     * @param templatePath 模板标识
//     * @param ctx          上下文参数
//     */
//    public String buildContent(String templatePath, Context ctx) {
//        if (StringUtils.isEmpty(templatePath) || null == ctx) {
//            throw GatewayException.error("缺少模板初始化必要参数");
//        }
//        return templateEngine.process(templatePath, ctx);
//    }

    //发件人，这里配置为 itmanagesys@glsc.com.cn
//    @Value("${senderEmail}")
    private String senderEmail;

    @Value("${spring.mail3.username}")
    private String senderEmailFrom;

    public MailService(MailProperties mailProperties) {
        this.senderEmail = mailProperties.getUsername();
    }

    public String getSenderEmail() {
        return senderEmail;
    }

    public void setSenderEmail(String senderEmail) {
        this.senderEmail = senderEmail;
    }

    /**
     * 获取发件人别称地址：别名<邮件地址>
     *
     * @return 返回带别称的邮件地址，如  资管产品管理系统<itmanagesys@glsc.com.cn>
     */
    public String getSenderEmailWithName() {
        String sender = "国联技术服务平台<" + senderEmail + ">";//发件人别名必须是：别名<邮件地址>格式

        return sender;
    }

    /**
     * 发送邮件
     *
     * @param recvMailList   邮件接收人邮箱列表
     * @param title          邮件标题
     * @param content        邮件内容
     * @param attachmentList 附件列表
     * @throws GatewayException
     */
    public String sendMail(List<String> recvMailList, String recipientNames, String title, String content, List<File> attachmentList) {
        if (CollectionUtils.isEmpty(recvMailList)) {
            logger.error("发送邮件时，收件人为空");
            return "";
        } else {
            return this.sendMail(recvMailList.toArray(new String[recvMailList.size()]), recipientNames, title, content, attachmentList);
        }
    }

    /**
     * 发送邮件
     *
     * @param recipientEmailArray 邮件接收人邮箱列表
     * @param recipientNames      邮件接收人名称，用于收件人称呼，如"张三，您好“，允许为空
     * @param title               邮件标题
     * @param content             邮件内容
     * @param attachmentList      附件列表，允许为空
     * @throws GatewayException
     */
//    @Transactional
    public String sendMail(String[] recipientEmailArray, String recipientNames, String title, String content, List<File> attachmentList) {
        return sendMail(recipientEmailArray, recipientNames, title, null, title, content, attachmentList, Constant.MAIL_TYPE_COMMON);
    }

    public String sendMail(String[] recipientEmailArray, String recipientNames, String title, String headTitle, String content, List<File> attachmentList, String mailType) {
        return sendMail(recipientEmailArray, recipientNames, title, null, headTitle, content, attachmentList, mailType);
    }

    public String sendMail(String[] recipientEmailArray, String recipientNames, String title, String titleLink, String headTitle, String content, List<File> attachmentList, String mailType) {
        List<String> mailInner = new ArrayList<String>();
        List<String> mailOut = new ArrayList<String>();
        if (recipientEmailArray == null || recipientEmailArray.length == 0) {
            throw GatewayException.error("接收人邮箱不能为空");
        }
        for (int i = 0; i < recipientEmailArray.length; i++) {
            //内部邮箱后缀为@glsc.com.cn或者未来资管子@glzqzg.com）
            if (recipientEmailArray[i].toLowerCase().endsWith("@glsc.com.cn") || recipientEmailArray[i].toLowerCase().endsWith("@glzqzg.com")) {
                mailInner.add(recipientEmailArray[i]);
            } else {
                mailOut.add(recipientEmailArray[i]);
            }
        }
        if (mailInner.size() > 0) {
            this.sendMailInner(mailInner.toArray(new String[0]), recipientNames, title, titleLink, headTitle, content, attachmentList, mailType);
        }
        if (mailOut.size() > 0) {
            this.sendMailOut(mailOut.toArray(new String[0]), recipientNames, title, titleLink, headTitle, content, attachmentList, mailType);
        }
        return null;
    }

    /**
     * 发送给内部
     *
     * @param recipientEmailArray
     * @param recipientNames
     * @param title
     * @param titleLink
     * @param headTitle
     * @param content
     * @param attachmentList
     * @param mailType
     * @return
     */
    public String sendMailInner(String[] recipientEmailArray, String recipientNames, String title, String titleLink, String headTitle, String content, List<File> attachmentList, String mailType) {
        if (null == recipientEmailArray || recipientEmailArray.length == 0) {
            throw GatewayException.error("接收人邮箱不能为空：");
        }

        String notSendRecvList = systemConfigService.findConfigValueByCode(Constant.CONFIG_KEY_NOT_SEND_RECV_LIST);
        List<String> recvMailList = Arrays.stream(recipientEmailArray).filter(item -> notSendRecvList == null || !notSendRecvList.contains(item)).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(recvMailList)) {
            logger.error("发送邮件时，收件人为空");
            return "";
        }

        recipientEmailArray = recvMailList.toArray(new String[recvMailList.size()]);
        String recipientEmailStr = StringUtils.join(recipientEmailArray, ",");
        InternetAddress[] recipientEmails = null;
        try {
            recipientEmails = InternetAddress.parse(recipientEmailStr);
        } catch (AddressException e) {
            logger.error("发送邮件时，收件人邮箱不合法：" + recipientEmailStr);
            throw GatewayException.error("收件人邮箱不合法：" + recipientEmailStr);
        }

        //邮件标题
        if (StringUtils.isEmpty(title) || StringUtils.isEmpty(content)) {
            throw GatewayException.error("发送邮件标题或内容不能为空，标题为" + title + "，邮件内容为" + content);
        }


        if (SpringUtil.isTestingByActiveProfile()) {//测试环境，强制增加测试标题
            title = TEST_MAIL_TITLE_PREFIX + title;
        }

        String mailId = "";
        MimeMessage mailMessage = null;
        MimeMessageHelper mailHelper = null;
        EmailClient emailClient = new EmailClient();
        try {
            mailMessage = mailSender.createMimeMessage();
            mailHelper = new MimeMessageHelper(mailMessage, true, "utf-8");
            logger.info("邮件服务初始化成功");
            String sender = this.getSenderEmailWithName();
            String recipient = recipientEmailStr;
            String randomStr = UUID.randomUUID().toString();

            //设置邮件内容*****************************************************************
            //绿色
            String emailHeadColor = "#10fa81";

            String helloNameStr = null;
            if (StringUtils.isEmpty(recipientNames)) {/*动态支持："你好"或者有收件人姓名的"张三，你好"*/
                helloNameStr = "";/*如果设置为null，则会出现null文本在邮件中，因此这里设置为空字符串*/
            } else {
                helloNameStr = StringUtils.trim(recipientNames) + "，";
            }
            String mailTemplate = getMailTemPlate(mailType);

            String currentTime = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");

            //TODO: 采用充血模型将各模板封装进map中
            //填充html模板中的参数
            String htmlText = Constant.MAIL_TYPE_IT_FLOW.equals(mailType) ?
                    MessageFormat.format(mailTemplate, emailHeadColor, titleLink, headTitle, content, currentTime)
                    : MessageFormat.format(mailTemplate, emailHeadColor, title, helloNameStr, content, currentTime);

            if (Constant.MAIL_TYPE_COMMON_LINK.equals(mailType)) {
                htmlText = MessageFormat.format(mailTemplate, emailHeadColor, title, helloNameStr, content, currentTime, titleLink);
            }

            //保存文件内容需要保存文件路径列表和文件名称列表供重新发送使用
            buildAttachmentList(attachmentList, mailHelper, emailClient);

            //存储邮件发送信息到t_am_email_client表中
            mailId = saveEmailClient(DictConstant.MAIL_TYPE_MAIL_DEFAULT, sender, recipient, title, htmlText, randomStr, emailClient.getFileNameList(), emailClient.getFilePathList());
            //End of 设置设置邮件内容*****************************************************

            mailHelper.setText(htmlText, true);//邮件内容


            //发送邮件，更新邮件状态为成功。
            mailHelper.setFrom(sender);
            mailHelper.setTo(recipientEmailArray);
            mailHelper.setSubject(title);
            SystemConfig config = systemConfigService.findByCode(SYSTEM_CONFIG_MAIL_SEND_ON);
            if (Objects.isNull(config) || Boolean.valueOf(config.getConfigValue())) {
                mailSender.send(mailMessage);
            }
            emailClientRepository.updateStatusByMailId(mailId, DictConstant.MAIL_STATUS_SUCCESS, "");

        } catch (SendFailedException e) {
            //进入这个异常就代表 出现了 某些 邮箱地址 是错误的情况  可能有人离职 邮箱 注销了
            logger.warn("存在邮箱无法发送,过滤异常邮箱再次发送,当前收件人清单:{},.", (Object[]) recipientEmailArray);

            try {//获取 正确的地址，再次尝试发送一次
                Address[] validAddressArray = e.getValidUnsentAddresses();
                String[] successEmailArray = null;
                if (validAddressArray != null && validAddressArray.length > 0) {
                    successEmailArray = new String[validAddressArray.length];
                    for (int k = 0; k < validAddressArray.length; k++) {
                        successEmailArray[k] = validAddressArray[k].toString();
                    }

                    logger.warn("存在邮箱无法发送,过滤异常邮箱再次发送,当前收件人清单：{},过滤后仅剩正确的收件人清单：{}"
                            , recipientEmailArray, successEmailArray);
                    mailHelper.setTo(successEmailArray);
                    mailSender.send(mailMessage);
                    String moreRemark = "存在异常邮箱，之前收件人：" + String.join(",", recipientEmailArray)
                            + ",过滤之后合法邮箱：" + String.join(",", successEmailArray);
                    emailClientRepository.updateStatusByMailId(mailId, DictConstant.MAIL_STATUS_SUCCESS, moreRemark);
                } else {
                    logger.error("收件邮箱：{}， 邮件标题： {}， 邮件内容：{}", emailClient.getRecipient(), emailClient.getTitle(), emailClient.getContent());
                    this.remindFailSendMail(mailId, e.getMessage());
                }
            } catch (Exception ex) {
                logger.error("收件邮箱：{}， 邮件标题： {}， 邮件内容：{}", emailClient.getRecipient(), emailClient.getTitle(), emailClient.getContent());
                this.remindFailSendMail(mailId, ex.getMessage());
            }
        } catch (Exception ex) {
            logger.error("收件邮箱：{}， 邮件标题： {}， 邮件内容：{}", emailClient.getRecipient(), emailClient.getTitle(), emailClient.getContent());
            this.remindFailSendMail(mailId, ex.getMessage());
        }
        return mailId;
    }

    /**
     * 发送给外部
     *
     * @param recipientEmailArray
     * @param recipientNames
     * @param title
     * @param titleLink
     * @param headTitle
     * @param content
     * @param attachmentList
     * @param mailType
     * @return
     */
    public String sendMailOut(String[] recipientEmailArray, String recipientNames, String title, String titleLink, String headTitle, String content, List<File> attachmentList, String mailType) {
        if (null == recipientEmailArray || recipientEmailArray.length == 0) {
            throw GatewayException.error("接收人邮箱不能为空：");
        }

        String notSendRecvList = systemConfigService.findConfigValueByCode(Constant.CONFIG_KEY_NOT_SEND_RECV_LIST);
        List<String> recvMailList = Arrays.stream(recipientEmailArray).filter(item -> notSendRecvList == null || !notSendRecvList.contains(item)).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(recvMailList)) {
            logger.error("发送邮件时，收件人为空");
            return "";
        }

        recipientEmailArray = recvMailList.toArray(new String[recvMailList.size()]);
        String recipientEmailStr = StringUtils.join(recipientEmailArray, ",");
        InternetAddress[] recipientEmails = null;
        try {
            recipientEmails = InternetAddress.parse(recipientEmailStr);
        } catch (AddressException e) {
            logger.error("发送邮件时，收件人邮箱不合法：" + recipientEmailStr);
            throw GatewayException.error("收件人邮箱不合法：" + recipientEmailStr);
        }

        //邮件标题
        if (StringUtils.isEmpty(title) || StringUtils.isEmpty(content)) {
            throw GatewayException.error("发送邮件标题或内容不能为空，标题为" + title + "，邮件内容为" + content);
        }


        if (SpringUtil.isTestingByActiveProfile()) {//测试环境，强制增加测试标题
            title = TEST_MAIL_TITLE_PREFIX + title;
        }

        String mailId = "";
        MimeMessage mailMessage = null;
        MimeMessageHelper mailHelper = null;
        EmailClient emailClient = new EmailClient();
        try {
            mailMessage = mailSender3.createMimeMessage();
            mailHelper = new MimeMessageHelper(mailMessage, true, "utf-8");
            logger.info("邮件服务初始化成功");
            String sender = "国联技术服务平台<" + senderEmailFrom + ">";
            String recipient = recipientEmailStr;
            String randomStr = UUID.randomUUID().toString();

            //设置邮件内容*****************************************************************
            //绿色
            String emailHeadColor = "#10fa81";

            String helloNameStr = null;
            if (StringUtils.isEmpty(recipientNames)) {/*动态支持："你好"或者有收件人姓名的"张三，你好"*/
                helloNameStr = "";/*如果设置为null，则会出现null文本在邮件中，因此这里设置为空字符串*/
            } else {
                helloNameStr = StringUtils.trim(recipientNames) + "，";
            }
            String mailTemplate = getMailTemPlate(mailType);

            String currentTime = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");

            //TODO: 采用充血模型将各模板封装进map中
            //填充html模板中的参数
            String htmlText = Constant.MAIL_TYPE_IT_FLOW.equals(mailType) ?
                    MessageFormat.format(mailTemplate, emailHeadColor, titleLink, headTitle, content, currentTime)
                    : MessageFormat.format(mailTemplate, emailHeadColor, title, helloNameStr, content, currentTime);

            if (Constant.MAIL_TYPE_COMMON_LINK.equals(mailType)) {
                htmlText = MessageFormat.format(mailTemplate, emailHeadColor, title, helloNameStr, content, currentTime, titleLink);
            }

            //保存文件内容需要保存文件路径列表和文件名称列表供重新发送使用
            buildAttachmentList(attachmentList, mailHelper, emailClient);

            //存储邮件发送信息到t_am_email_client表中
            mailId = saveEmailClient(DictConstant.MAIL_TYPE_MAIL_DEFAULT, sender, recipient, title, htmlText, randomStr, emailClient.getFileNameList(), emailClient.getFilePathList());
            //End of 设置设置邮件内容*****************************************************

            mailHelper.setText(htmlText, true);//邮件内容


            //发送邮件，更新邮件状态为成功。
            mailHelper.setFrom(sender);
            mailHelper.setTo(recipientEmailArray);
            mailHelper.setSubject(title);

            mailSender3.send(mailMessage);
            emailClientRepository.updateStatusByMailId(mailId, DictConstant.MAIL_STATUS_SUCCESS, "");

        } catch (SendFailedException e) {
            //进入这个异常就代表 出现了 某些 邮箱地址 是错误的情况  可能有人离职 邮箱 注销了
            logger.warn("存在邮箱无法发送,过滤异常邮箱再次发送,当前收件人清单:{},.", (Object[]) recipientEmailArray);

            try {//获取 正确的地址，再次尝试发送一次
                Address[] validAddressArray = e.getValidUnsentAddresses();
                String[] successEmailArray = null;
                if (validAddressArray != null && validAddressArray.length > 0) {
                    successEmailArray = new String[validAddressArray.length];
                    for (int k = 0; k < validAddressArray.length; k++) {
                        successEmailArray[k] = validAddressArray[k].toString();
                    }

                    logger.warn("存在邮箱无法发送,过滤异常邮箱再次发送,当前收件人清单：{},过滤后仅剩正确的收件人清单：{}"
                            , recipientEmailArray, successEmailArray);
                    mailHelper.setTo(successEmailArray);
                    mailSender3.send(mailMessage);
                    String moreRemark = "存在异常邮箱，之前收件人：" + String.join(",", recipientEmailArray)
                            + ",过滤之后合法邮箱：" + String.join(",", successEmailArray);
                    emailClientRepository.updateStatusByMailId(mailId, DictConstant.MAIL_STATUS_SUCCESS, moreRemark);
                } else {
                    logger.error("收件邮箱：{}， 邮件标题： {}， 邮件内容：{}", emailClient.getRecipient(), emailClient.getTitle(), emailClient.getContent());
                    this.remindFailSendMail(mailId, e.getMessage());
                }
            } catch (Exception ex) {
                logger.error("收件邮箱：{}， 邮件标题： {}， 邮件内容：{}", emailClient.getRecipient(), emailClient.getTitle(), emailClient.getContent());
                this.remindFailSendMail(mailId, ex.getMessage());
            }
        } catch (Exception ex) {
            logger.error("收件邮箱：{}， 邮件标题： {}， 邮件内容：{}", emailClient.getRecipient(), emailClient.getTitle(), emailClient.getContent());
            this.remindFailSendMail(mailId, ex.getMessage());
        }
        return mailId;
    }

    /**
     * 邮件发送失败给管理员发送提醒
     */
    private void remindFailSendMail(String mailId, String failMessage) {
        if (StringUtils.isEmpty(mailId)) {
            return;
        }

        logger.error("邮件发送异常，邮件id为{},原因：{}", mailId, failMessage);

        //更新邮件发送失败状态及原因。
        String failReason = DateUtil.format(new Date(), "yyyy-MM-dd hh:mm:ss SSS") + "###" + failMessage;
        failReason = failReason.length() > 500 ? failReason.substring(0, 500) : failReason;

        emailClientRepository.updateFailReasonByMailId(mailId, failReason);
//
//        //邮件发送失败，给管理员发送短信提醒
//        messageSender.sendShortMessageToAdmin("邮件发送异常,请登录系统查看");
        //向管理员报告邮件发送失败
        this.sendMailToAdmin(Constant.MAIL_TITLE_SEND_FAILURE, "邮件发送编码为: " + mailId + "的邮件发送失败，请检查！");
    }

    /**
     * 保存邮件内容单独出来可以复用
     *
     * @param mailType
     * @param sender
     * @param recipient
     * @param title
     * @param htmlText
     * @param randomStr
     * @param fileNameList
     * @param filePathList
     * @return
     */
    private String saveEmailClient(String mailType, String sender, String recipient, String title, String htmlText, String randomStr, String fileNameList, String filePathList) {
        EmailClient ec = new EmailClient();
        ec.setMailType(mailType);
        ec.setSender(sender);
        ec.setRecipient(recipient);
        ec.setTitle(title);
        ec.setContent(htmlText);
        ec.setRandomStr(randomStr);
        ec.setStatus(DictConstant.MAIL_STATUS_TODO);
        ec.setFileNameList(fileNameList);
        ec.setFilePathList(filePathList);
        String mailId = emailClientRepository.save(ec).getMailId() + "";
        return mailId;
    }

    /**
     * 处理邮件附件单独出来可以复用
     *
     * @param attachmentList
     * @param helper
     * @param ec
     * @throws MessagingException
     */
    private void buildAttachmentList(List<File> attachmentList, MimeMessageHelper helper, EmailClient ec) throws MessagingException, UnsupportedEncodingException {
        //保存文件内容需要保存文件路径列表和文件名称列表供重新发送使用
        StringBuilder filePathListApp = new StringBuilder("");
        StringBuilder fileNameListApp = new StringBuilder("");
        String fileNameList = null;
        String filePathList = null;
        if (!CollectionUtils.isEmpty(attachmentList)) {//附件不为空
            for (File attachment : attachmentList) {
                helper.addAttachment(MimeUtility.encodeWord(attachment.getName(), "UTF-8", "B"), attachment);
                filePathListApp.append(attachment.getAbsolutePath()).append(",");
                fileNameListApp.append(attachment.getName()).append(",");
            }
            filePathList = filePathListApp.toString();
            fileNameList = fileNameListApp.toString();
            filePathList = filePathList.substring(0, filePathList.length() - 1);
            fileNameList = fileNameList.substring(0, fileNameList.length() - 1);
            ec.setFilePathList(filePathList);
            ec.setFileNameList(fileNameList);
        }
    }


    /*
     * 邮件重发
     * */
    public String reSendMail(EmailClient emailClient) {

        checkEmailValid(emailClient);

        String mailId = emailClient.getMailId() + "";

        String[] recipientEmailArray = emailClient.getRecipient().split(",");
        MimeMessage mailMessage = null;
        MimeMessageHelper mailHelper = null;
        try {

            mailMessage = mailSender.createMimeMessage();
            mailHelper = new MimeMessageHelper(mailMessage, true);
            //发送邮件，更新邮件状态为成功。
            mailHelper.setFrom(emailClient.getSender());
            if (emailClient.getRecipient().contains(",")) {
                mailHelper.setTo(emailClient.getRecipient().split(","));
            } else {
                mailHelper.setTo(emailClient.getRecipient());
            }
            mailHelper.setSubject(emailClient.getTitle());
            mailHelper.setText(emailClient.getContent(), true);//邮件内容

            //重新发送增加追加附件
            String fileNameList = emailClient.getFileNameList();
            String filePathList = emailClient.getFilePathList();
            if (StringUtils.isNotEmpty(fileNameList) && StringUtils.isNotEmpty(filePathList)) {
                String[] fileNames = fileNameList.split(",");
                String[] filePaths = filePathList.split(",");
                for (int i = 0; i < fileNames.length; i++) {
                    mailHelper.addAttachment(MimeUtility.encodeWord(fileNames[i], "UTF-8", "B"), new File(filePaths[i]));
                }
            }

            /**
             * 邮箱类型是邮箱二的的邮件使用邮箱二的配置发送，默认和邮箱类型是邮箱一的使用默认邮箱发送
             * 改：统一由邮箱一发送
             */
            mailSender.send(mailMessage);
//            emailClientRepository.updateStatusByMailId(mailId, DictConstant.MAIL_STATUS_SUCCESS, "");
            return DictConstant.YES;
        } catch (SendFailedException e) {
            //进入这个异常就代表 出现了 某些 邮箱地址 是错误的情况  可能有人离职 邮箱 注销了
            logger.warn("存在邮箱无法发送,过滤异常邮箱再次发送,当前收件人清单:{},.", (Object[]) recipientEmailArray);

            try {//获取 正确的地址，再次尝试发送一次
                Address[] validAddressArray = e.getValidUnsentAddresses();
                String[] successEmailArray = null;
                if (validAddressArray != null && validAddressArray.length > 0) {
                    successEmailArray = new String[validAddressArray.length];
                    for (int k = 0; k < validAddressArray.length; k++) {
                        successEmailArray[k] = validAddressArray[k].toString();
                    }

                    logger.warn("存在邮箱无法发送,过滤异常邮箱再次发送,当前收件人清单：{},过滤后仅剩正确的收件人清单：{}"
                            , recipientEmailArray, successEmailArray);
                    mailHelper.setTo(successEmailArray);//重新定义，仅成功的用户
                    if (DictConstant.MAIL_TYPE_MAIL_OTHER.equals(emailClient.getMailType())) {
                        mailSender.send(mailMessage);
                    }
                    String moreRemark = "存在异常邮箱，之前收件人：" + String.join(",", recipientEmailArray)
                            + ",过滤之后合法邮箱：" + String.join(",", successEmailArray);
//                    emailClientRepository.updateStatusByMailId(mailId, DictConstant.MAIL_STATUS_SUCCESS, moreRemark);
                } else {
                    logger.error("收件邮箱：{}， 邮件标题： {}， 邮件内容：{}", emailClient.getRecipient(), emailClient.getTitle(), emailClient.getContent());
                    this.remindFailSendMail(mailId, e.getMessage());
                }
            } catch (Exception ex) {
                logger.error("收件邮箱：{}， 邮件标题： {}， 邮件内容：{}", emailClient.getRecipient(), emailClient.getTitle(), emailClient.getContent());
                this.remindFailSendMail(mailId, ex.getMessage());
            }
        } catch (Exception ex) {
            logger.error("收件邮箱：{}， 邮件标题： {}， 邮件内容：{}", emailClient.getRecipient(), emailClient.getTitle(), emailClient.getContent());
            this.remindFailSendMail(mailId, ex.getMessage());
        }
        return DictConstant.NO;
    }

    /*检查发件信息是否合法*/
    protected void checkEmailValid(EmailClient emailClient) {
        if (emailClient == null) {
            throw GatewayException.error("发件信息不能为空");
        }
        checkEmailValid(emailClient.getSender(), emailClient.getRecipient(), emailClient.getTitle());
    }

    /*检查发件信息是否合法*/
    protected void checkEmailValid(String sender, String recipient, String title) {
        if (sender == null || sender.isEmpty()) {
            throw GatewayException.error("发件人不能为空");
        }
        if (recipient == null || recipient.isEmpty()) {
            throw GatewayException.error("收件人不能为空");
        }
        if (title == null || title.isEmpty()) {
            throw GatewayException.error("邮件标题不能为空");
        }
    }

    /**
     * 根据邮件模板类型获取模板内容
     *
     * @pram type 邮件模板类型
     */

    private String getMailTemPlate(String type) throws Exception {
        //加载邮件html模板
        String fileName = "";
        if (Constant.MAIL_TYPE_RESPONSIBLE_CONFIRM.equals(type)) {
            fileName = Constant.TEMPLATE_NAME_CONFIRM_INFO;
        } else if (Constant.MAIL_TYPE_ELIG_AUDIT.equals(type)) {
            fileName = Constant.TEMPLATE_NAME_ELIG_CHECK;
        } else if (Constant.MAIL_TYPE_EXPIRE_REMIND.equals(type)) {
            fileName = Constant.TEMPLATE_NAME_EXPIRE_REMIND;
        } else if (Constant.MAIL_TYPE_AUDIT_REJECT.equals(type)) {
            fileName = Constant.TEMPLATE_NAME_AUDIT_REJECT;
        } else if (Constant.MAIL_TYPE_ACCOUNT_OPEN.equals(type)) {
            fileName = Constant.TEMPLATE_NAME_ACCOUNTTYPE_OPEN;
        } else if (Constant.MAIL_TYPE_COMMON.equals(type)) {
            fileName = Constant.TEMPLATE_NAME_TYPE_COMMON;
        } else if (Constant.MAIL_TYPE_IT_FLOW.equals(type)) {
            fileName = Constant.TEMPLATE_NAME_TYPE_IT_FLOW;
        } else if (Constant.MAIL_TYPE_REPORT.equals(type)) {
            fileName = Constant.TEMPLATE_NAME_TYPE_REPORT;
        } else if (Constant.MAIL_TYPE_REMIND_FEE_CARRY.equals(type)) {
            fileName = Constant.TEMPLATE_NAME_TYPE_REMIND_FEE_CARRY;
        } else if (Constant.MAIL_TYPE_CUSTODIAN.equals(type)) {
            fileName = Constant.TEMPLATE_NAME_TYPE_CUSTODIAN;
        } else if (Constant.MAIL_TYPE_COMMON_LINK.equals(type)) {
            fileName = Constant.TEMPLATE_NAME_TYPE_COMMON_LINK;
        } else {
            throw GatewayException.error("未找到邮件模板");
        }

        InputStream inputStream = MailService.class.getClassLoader().getResourceAsStream(fileName);
        BufferedReader fileReader = new BufferedReader(new InputStreamReader(inputStream));

        StringBuffer buffer = new StringBuffer();
        String line = null;

        try {
            while ((line = fileReader.readLine()) != null) {
                buffer.append(line);
            }
        } catch (Exception e) {
            logger.error("读取邮件模板文件" + fileName + "时发生异常!", e);
        } finally {
            inputStream.close();
            fileReader.close();
        }

        return buffer.toString();
    }


    /**
     * 向管理员发送邮件提醒
     */
    @SneakyThrows
    public void sendMailToAdmin(String title, String content) {
        try {
            if (SpringUtil.isTestingByActiveProfile()) {
                title = TEST_MAIL_TITLE_PREFIX + title;
            }

            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            String sender = this.getSenderEmailWithName();

            String recipientStr = systemConfigService.findByCode(Constant.CONFIG_KEY_ADMIN_EMAIL_ADDR).getConfigValue();
            recipientStr = recipientStr.replace("，", ",");
            String[] recipientStrArray = recipientStr.split(",");
            String mailId = saveEmailClient(DictConstant.MAIL_TYPE_MAIL_DEFAULT, sender, recipientStr, title, content, null, null, null);
//            logger.info("保存发送邮件成功：mailId=" + mailId);

            helper.setFrom(sender);
            helper.setTo(recipientStrArray);//一次性可以发送多个
            helper.setSubject(title);
            helper.setText(content==null?"":content, true);//邮件内容

            if (SpringUtil.isTestingByActiveProfile()) {
                logger.error("开发测试环境，邮件发送异常，不再发送短信，因为测试环境无短信测试环境，短信发送会失败");
            } else {//生产环境，才真正发送短信
                mailSender.send(message);
            }
//            emailClientRepository.updateStatusByMailId(mailId, DictConstant.MAIL_STATUS_SUCCESS, "");
        } catch (Exception ex) {
            logger.error("向管理员发送邮件异常message：" + ex.getLocalizedMessage(), ex);
            logger.error("邮件标题： " + title + "， 邮件内容：" + content + "");
            throw ex;
//            messageSender.sendShortMessageToAdmin("向管理员发送邮件异常,请登录系统查看");
        }
    }


//    /**
//     * 产品年报发送接口，独立邮箱发送
//     * @param er 发送报告内容
//     */
//    public void sendReport(EmailReport er) throws Exception {
//        String mailId = "";
//        try {
//            MimeMessage message = mailSender2.createMimeMessage();
//            MimeMessageHelper helper = new MimeMessageHelper(message, true, "utf-8");
//            String sender = er.getSender();
//            String recipients = er.getRecipient();
//            String randomStr = UUID.randomUUID().toString();
//            String title = er.getTitle();
//            checkEmailValid(sender, recipients, title);
//            helper.setFrom(sender);
//            Set<String> recivers = Arrays.asList(recipients.split(",")).stream()
//                    .map(reciver -> reciver.trim())
//                    .filter(reciver -> !reciver.isEmpty())
//                    .collect(Collectors.toSet());
//            String[] to = new String[recivers.size()];
//            helper.setTo(recivers.toArray(to));
//            helper.setSubject(title);
//
//            String mailTemplate = getMailTemPlate(Constant.MAIL_TYPE_REPORT);
//
//            String context = er.getContext();
//            String[] cs = context.split(",");
//
//            //填充html模板中的参数
//            String htmlText = MessageFormat.format(mailTemplate, cs[0], cs[1]);
//            helper.setText(htmlText, true);
//            //添加附件
//            List<DocumentInfo> attachments = er.getAttachments();
//            List<File> attachmentList = new ArrayList<>();
//            String uploadRoot = systemConfigService.findConfigValueByCode(Constant.CONFIG_KEY_UPLOAD_ROOT);
//            if (attachments != null && !attachments.isEmpty()) {
//                for (DocumentInfo di : attachments) {
//                    File file = new File(uploadRoot + File.separator + di.getFilePath());
//                    attachmentList.add(file);
//                }
//            }
//            EmailClient ec = new EmailClient();
//            buildAttachmentList(attachmentList, helper, ec);
//            mailId = saveEmailClient(DictConstant.MAIL_TYPE_MAIL_OTHER, sender, recipients, title, htmlText, randomStr, ec.getFileNameList(), ec.getFilePathList());
//            mailSender2.send(message);
//            emailClientRepository.updateStatusByMailId(mailId, DictConstant.MAIL_STATUS_SUCCESS,"");
//        } catch (Exception ex) {
//            //记录异常
//            if (StringUtils.isNotBlank(mailId)) {
//                logger.error("邮件发送异常，原因：" + ex.getLocalizedMessage(), ex);
//                logger.error("邮件发送过程出现异常，邮件id为：" + mailId);
//
//                //更新邮件发送失败状态及原因。
//                String failReason = DateUtil.format(new Date(), "yyyy-MM-dd hh:mm:ss SSS") + "###" + ex.getMessage();
//                failReason = failReason.length() > 500 ? failReason.substring(0, 500) : failReason;
//
//                emailClientRepository.updateFailReasonByMailId(mailId, failReason);
//
//                //邮件发送失败，给管理员发送短信提醒
//                messageSender.sendShortMessageToAdmin("邮件发送异常,请登录系统查看");
//                //向管理员报告邮件发送失败
//                this.sendMailToAdmin(Constant.MAIL_TITLE_SEND_FAILURE, "邮件发送编码为: " + mailId + "的邮件发送失败，请检查！");
//            } else {
//                logger.error("邮件服务初始化失败message：" + ex.getMessage(), ex);
//                logger.error("收件邮箱：" + er.getRecipient() + "， 邮件标题： " + er.getTitle() + "， 邮件内容：" + er.getContext() + "");
//            }
//        }
//    }
//
//    /**
//     * 产品开放期调整发送接口，独立邮箱发送
//     * @param er 发送报告内容
//     */
//    public void sendCustodian(EmailReport er) throws Exception {
//        String mailId = "";
//        try {
//            MimeMessage message = mailSender2.createMimeMessage();
//            MimeMessageHelper helper = new MimeMessageHelper(message, true, "utf-8");
//            String sender = er.getSender();
//            String recipients = er.getRecipient();
//            String randomStr = UUID.randomUUID().toString();
//            String title = er.getTitle();
//            checkEmailValid(sender, recipients, title);
//            helper.setFrom(sender);
//            Set<String> recivers = Arrays.asList(recipients.split(",")).stream()
//                    .map(reciver -> reciver.trim())
//                    .filter(reciver -> !reciver.isEmpty())
//                    .collect(Collectors.toSet());
//            String[] to = new String[recivers.size()];
//            helper.setTo(recivers.toArray(to));
//            helper.setSubject(title);
//
//            String mailTemplate = getMailTemPlate(Constant.MAIL_TYPE_CUSTODIAN);
//
//            String context = er.getContext();
//
//            //填充html模板中的参数
//            String htmlText = MessageFormat.format(mailTemplate, context);
//            helper.setText(htmlText, true);
//            //添加附件
//            List<DocumentInfo> attachments = er.getAttachments();
//            List<File> attachmentList = new ArrayList<>();
//            String uploadRoot = systemConfigService.findConfigValueByCode(Constant.CONFIG_KEY_UPLOAD_ROOT);
//            if (attachments != null && !attachments.isEmpty()) {
//                for (DocumentInfo di : attachments) {
//                    File file = new File(uploadRoot + File.separator + di.getFilePath());
//                    attachmentList.add(file);
//                }
//            }
//            EmailClient ec = new EmailClient();
//            buildAttachmentList(attachmentList, helper, ec);
//            mailId = saveEmailClient(DictConstant.MAIL_TYPE_MAIL_OTHER, sender, recipients, title, htmlText, randomStr, ec.getFileNameList(), ec.getFilePathList());
//            mailSender2.send(message);
//            emailClientRepository.updateStatusByMailId(mailId, DictConstant.MAIL_STATUS_SUCCESS,"");
//        } catch (Exception ex) {
//            //记录异常
//            if (StringUtils.isNotBlank(mailId)) {
//                logger.error("邮件发送异常，原因：" + ex.getLocalizedMessage(), ex);
//                logger.error("邮件发送过程出现异常，邮件id为：" + mailId);
//
//                //更新邮件发送失败状态及原因。
//                String failReason = DateUtil.format(new Date(), "yyyy-MM-dd hh:mm:ss SSS") + "###" + ex.getMessage();
//                failReason = failReason.length() > 500 ? failReason.substring(0, 500) : failReason;
//
//                emailClientRepository.updateFailReasonByMailId(mailId, failReason);
//
//                //邮件发送失败，给管理员发送短信提醒
//                messageSender.sendShortMessageToAdmin("邮件发送异常,请登录系统查看");
//                //向管理员报告邮件发送失败
//                this.sendMailToAdmin(Constant.MAIL_TITLE_SEND_FAILURE, "邮件发送编码为: " + mailId + "的邮件发送失败，请检查！");
//            } else {
//                logger.error("邮件服务初始化失败message：" + ex.getMessage(), ex);
//                logger.error("收件邮箱：" + er.getRecipient() + "， 邮件标题： " + er.getTitle() + "， 邮件内容：" + er.getContext() + "");
//            }
//        }
//    }
//
//
//    /**
//     * 根据code查询systemConfig
//     */
//    private SystemConfig findByCode(String configCode) {
//        SystemConfig config = new SystemConfig();
//        config.setConfigCode(configCode);
//        Example<SystemConfig> example = Example.of(config);
//        Optional<SystemConfig> one = systemConfigRepository.findOne(example);
//        return one.get();
//    }
//

    /**
     * 修改邮件记录
     */
    public EmailClient update(EmailClient updateEmailClient) {
        if (updateEmailClient == null || updateEmailClient.getMailId() == null
                || StringUtils.isEmpty(updateEmailClient.getContent())
        ) {
            throw GatewayException.error("修改邮件记录时，邮件信息、邮件ID不能为空");
        }
        emailClientRepository.save(updateEmailClient);
        return updateEmailClient;
    }

    public void sendSimpleMail(String to, String subject, String context) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(senderEmail);
        message.setTo(to);
        message.setSubject(subject);
        message.setText(context);
        mailSender.send(message);

    }

    @SneakyThrows
    public void sendMailToAdminWithOutDB(String title, String content) {
        try {
            if (SpringUtil.isTestingByActiveProfile()) {
                title = TEST_MAIL_TITLE_PREFIX + title;
            }

            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            String sender = this.getSenderEmailWithName();

            String recipientStr = "weizt@glsc.com.cn";
            String[] recipientStrArray = recipientStr.split(",");
//            String mailId = saveEmailClient(DictConstant.MAIL_TYPE_MAIL_DEFAULT, sender, recipientStr, title, content, null, null, null);
//            logger.info("保存发送邮件成功：mailId=" + mailId);

            helper.setFrom(sender);
            helper.setTo(recipientStrArray);//一次性可以发送多个
            helper.setSubject(title);
            helper.setText(content==null?"":content, true);//邮件内容

            if (SpringUtil.isTestingByActiveProfile()) {
                logger.error("开发测试环境，邮件发送异常，不再发送短信，因为测试环境无短信测试环境，短信发送会失败");
            } else {//生产环境，才真正发送短信
                mailSender.send(message);
            }
//            emailClientRepository.updateStatusByMailId(mailId, DictConstant.MAIL_STATUS_SUCCESS, "");
        } catch (Exception ex) {
            logger.error("向管理员发送邮件异常message：" + ex.getLocalizedMessage(), ex);
            logger.error("邮件标题： " + title + "， 邮件内容：" + content + "");
            throw ex;
//            messageSender.sendShortMessageToAdmin("向管理员发送邮件异常,请登录系统查看");
        }
    }
}

